package com.bw.http.utils.zgr

import com.alibaba.android.arouter.launcher.ARouter
import com.bw.base.constants.ApiConst
import com.bw.base.constants.BaseConst
import com.bw.base.constants.RoutePath
import com.bw.http.BuildConfig
import com.bw.http.utils.Res
import com.google.gson.Gson
import com.tencent.mmkv.MMKV
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create
import java.net.Proxy
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLServerSocket
import javax.net.ssl.SSLServerSocketFactory
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager

object HttpManager {

    /**
     * 获取OkHttpClient
     *
     * 1.底层基于HttpURLConnection实现
     * 2.使用线程池管理所有清求连接（连接池），默认最大64个链接
     * 3.请求和返回处理时采用责任链的设计模式（拦截器）
     * 4.采用调度器管理请求
     *
     * 以下封装存在的问题
     * OkHttpClient和Retrofit有多份实例
     * 开启多个线程池，导致内存浪费
     * 链接请求没有复用，导致线程浪费
     * 单个链接时间长
     * 没有对请求进行统一处理，如关闭请求
     */
    private fun getOkHttpClient(): OkHttpClient {
        val okBuilder = OkHttpClient.Builder()
        okBuilder.apply {

            connectTimeout(BaseConst.CONNECT_TIME_OUT, TimeUnit.SECONDS)
            readTimeout(BaseConst.READ_TIME_OUT, TimeUnit.SECONDS)
            writeTimeout(BaseConst.WRITE_TIME_OUT, TimeUnit.SECONDS)

            //设置接口请求日志拦截器
            if (BuildConfig.isOpenLog) {
                addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            }

            //Header参数拦截器
            addInterceptor(getHeaderInterceptor())

            //服务器异常拦截器
            addInterceptor(getServiceExceptionInterceptor())

            //添加https支持
            sslSocketFactory(sslSocketFactory, trustManager)

            //禁用代理来防止装包
            proxy(Proxy.NO_PROXY)


        }
        return okBuilder.build()
    }

    /**
     * 获取Retrofit
     */
    private fun getRetrofit(): Retrofit {
        val retrofitBuilder = Retrofit.Builder()


        //apply扩展函数用于对象赋值,返回当前对象
        retrofitBuilder.apply {
            baseUrl(BuildConfig.BASE_URL)
            client(getOkHttpClient())
            addConverterFactory(GsonConverterFactory.create())
        }
        return retrofitBuilder.build()
    }


    /**
     * 请求头拦截器
     */
    private fun getHeaderInterceptor(): Interceptor {
        return object : Interceptor {
            override fun intercept(chain: Interceptor.Chain): Response {

                val builder = chain.request().newBuilder()


                val token = MMKV.defaultMMKV().decodeString(ApiConst.PARAM_TOKEN, "park2208")
                if (token != null) {
                    builder.header(ApiConst.PARAM_TOKEN, token)
                }
                val accessId = MMKV.defaultMMKV().decodeString(ApiConst.PARAM_ACCESS_ID, "")
                if (accessId != null) {
                    builder.header(ApiConst.PARAM_ACCESS_ID, accessId)
                }

                val request = builder.build()
                val response = chain.proceed(request)

                //验证token是否过期
                if (response.code == 403 || response.code == 401) {
                    ARouter.getInstance().build(RoutePath.PATH_LOGIN).navigation()
                }

                return response
            }
        }
    }


    /**
     * 服务器异常拦截器
     */
    private fun getServiceExceptionInterceptor(): Interceptor {
        return object : Interceptor {
            override fun intercept(chain: Interceptor.Chain): Response {


                val errorResponse = chain.proceed(chain.request())
                val builder = errorResponse.newBuilder()

                if (errorResponse.code == 500) {
                    val res = Res(500, "服务器异常", "请联系客服")

                    builder.body(
                        Gson().toJson(res)
                            .toResponseBody("application/json;charset=UTF-8".toMediaTypeOrNull())
                    )
                }

                return errorResponse
            }
        }
    }

    /**
     * 获取ApiService实例对象
     */
    fun <T> getApiService(clazz: Class<*>): T {
        return getRetrofit().create(clazz) as T
    }

    private val sslSocketFactory: SSLSocketFactory
        get() = try {
            val sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, arrayOf(), SecureRandom())
            sslContext.socketFactory
        } catch (e: Exception) {
            throw RuntimeException(e)
        }



    private val trustManager:X509TrustManager
    get() = object :X509TrustManager{
        override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {
        }

        override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {
        }

        override fun getAcceptedIssuers(): Array<X509Certificate> {
            return arrayOf()
        }
    }

}